<template>
  <v-row class="pa-1 formOperationStyle" :align="formOperation.rowAlign" :justify="formOperation.rowJustify">
    <base-button
      v-if="cancelBtn.show"
      :class="cancelBtn.class"
      :btn-item-config="cancelBtn"
      @buttonCB="buttonCB"
    ></base-button>
    <base-button
      v-if="saveBtn.show"
      :class="saveBtn.class"
      :btn-item-config="saveBtn"
      @buttonCB="buttonCB"
    ></base-button>
    <base-button
      v-for="btn in buttonList"
      :key="btn.id"
      :btn-item-config="btn"
      :class="btn.class"
      @buttonCB="buttonListMethodCB"
    ></base-button>
  </v-row>
</template>

<script>
import { assignObject, isEmptyValue } from '@/utils/tools'
import BaseButton from '../BaseSingleComponent/BaseButton.vue'
export default {
  // 表单操作组件
  name: 'FormOperation',

  components: { BaseButton },

  model: {
    prop: 'formOperation',
    event: 'setFormOperation'
  },

  props: {
    // 表单操作项配置
    formOperation: { type: Object, default: () => ({}) }
  },

  data() {
    return {
      // 取消按钮
      cancelBtn: this.formOperation.cancelBtn,
      // 保存按钮
      saveBtn: this.formOperation.saveBtn,
      // 自定义按钮集
      buttonList: [],
      // 按钮默认边距样式
      defaultClassName: 'ma-2'
    }
  },

  computed: {},

  created() {
    // 设置自定义按钮集
    this.setDefualtButtonList()

    // 设置默认表单操作项的配置属性
    this.setFormOperatinoDefaultAttributes()

    // 初始化时创建空按钮对象 start
    isEmptyValue(this.formOperation.cancelBtn) && (this.formOperation.cancelBtn = {})
    isEmptyValue(this.formOperation.saveBtn) && (this.formOperation.saveBtn = {})
    // 初始化时创建空按钮对象 end

    // 创建 取消/保存 按钮 start
    this.setCancelBtnDefaultAttributes()
    this.setSaveBtnDefaultAttributes()
    // 创建 取消/保存 按钮 end

    this.setButtonListClassName()
  },

  methods: {
    /** 设置默认表单操作项的配置属性 */
    setFormOperatinoDefaultAttributes() {
      let defaultFormOperation = { rowAlign: 'center', rowJustify: 'center' }
      defaultFormOperation = { ...Object.assign(defaultFormOperation, this.formOperation) }
      Object.keys(defaultFormOperation).forEach(key => (this.formOperation[key] = defaultFormOperation[key]))
    },

    // 设置 取消/保存 默认属性 start
    setCancelBtnDefaultAttributes() {
      const defaultCancelBtn = {
        title: this.$t('btn.cancel'),
        show: true,
        method: 'formCancel',
        color: 'error',
        // icon: 'formCancel'
        icon: 'close',
        iconType: 'mdi'
      }
      this.setBtnDefaultAttributes(defaultCancelBtn, 'cancelBtn', 'cancelBtnClass')
      this.setDefaultBtnShow('cancelBtn', 'cancelBtnShow')
    },
    setSaveBtnDefaultAttributes() {
      const defaultSaveBtn = {
        title: this.$t('btn.save'),
        show: true,
        method: 'formSave',
        color: 'primary',
        // icon: 'formSave',
        icon: 'check',
        iconType: 'mdi'
      }
      this.setBtnDefaultAttributes(defaultSaveBtn, 'saveBtn', 'saveBtnClass')
      this.setDefaultBtnShow('saveBtn', 'saveBtnShow')
    },
    /**
     * 提取 取消/保存 默认属性方法
     */
    setBtnDefaultAttributes(defaultAttributes, insertBtn, outClassNameProp) {
      this.setDefaultBtnClassName(insertBtn, outClassNameProp)
      // 合并 默认按钮参数 和 自定义按钮参数
      this.formOperation[insertBtn] = assignObject(defaultAttributes, this.formOperation[insertBtn])
    },
    // 取消/保存 的样式拼接方法
    setDefaultBtnClassName(insertBtn, outClassNameProp) {
      /**
       * 获取定义的 按钮 class 名称
       * 两种定义方式:
       *   1. 直接在 formOperation 下直接定义 -> 取消/保存 按钮样式名; 例如: formOperation.cancelBtnClass / formOperation.saveBtnClass
       *   2. 在相应按钮中定义样式; 例如: formOperation.cancelBtn.class / formOperation.saveBtn.class
       */
      // 定义方式 1 的样式名 外部样式 outClassName
      const outClassName = this.formOperation[outClassNameProp]
      // 定义方式 2 的样式名 内部样式 insideClassName
      const insideClassName = this.formOperation[insertBtn].class
      /**
       * 拼接样式
       * 判断 外部样式 outClassName 是否为空
       *  1. 为空 true -> 继续判断 内部样式 insideClassName 是否为空
       *     1.1 为空 true -> this.formOperation[insertBtn].class = this.defaultClassName 设置默认值
       *     1.2 不为空 false -> this.formOperation[insertBtn].class = this.defaultClassName + ' ' + insideClassName 拼接样式
       *  2. 不为空 false
       *     2.1 为空 true -> this.formOperation[insertBtn].class = this.defaultClassName + ' ' + outClassName 拼接样式
       *     2.2 不为空 false -> this.formOperation[insertBtn].class = this.defaultClassName + ' ' + insideClassName + ' ' + outClassName 拼接样式
       */
      if (isEmptyValue(outClassName)) {
        isEmptyValue(insideClassName)
          ? (this.formOperation[insertBtn].class = this.defaultClassName)
          : (this.formOperation[insertBtn].class = this.defaultClassName + ' ' + insideClassName)
      } else {
        isEmptyValue(insideClassName)
          ? (this.formOperation[insertBtn].class = this.defaultClassName + ' ' + outClassName)
          : (this.formOperation[insertBtn].class = this.defaultClassName + ' ' + insideClassName + ' ' + outClassName)
      }
      // 删除 外部样式名 规范参数地址
      delete this.formOperation[outClassNameProp]
    },
    // 取消/保存 的显隐控制方法
    setDefaultBtnShow(insertBtn, showFlagProp) {
      /**
       * 是否显示默认 取消/保存 按钮
       * 两种定义方式:
       *   1. 直接在 formOperation 下直接定义 -> 取消/保存 按钮显隐; 例如: formOperation.cancelBtnShow / formOperation.saveBtnShow
       *   2. 在相应按钮中定义显隐; 例如: formOperation.cancelBtn.show / formOperation.saveBtn.show
       */
      // 外部定义显隐 outShowFlag
      const outShowFlag = this.formOperation[showFlagProp]
      // 内部定义显隐 insideShowFlag
      const insideShowFlag = this.formOperation[insertBtn].show
      // 只要定义了 cancelBtnShow / saveBtnShow 为 false 则不显示
      if (!isEmptyValue(outShowFlag)) {
        this.formOperation[insertBtn].show = Boolean(outShowFlag) && Boolean(insideShowFlag)
        // 删除 外部显隐参数 规范参数地址
        delete this.formOperation[showFlagProp]
      }
      // 解构参数, 保持参数一致
      this[insertBtn] = { ...this.formOperation[insertBtn] }
    },
    // 设置 取消/保存 默认属性 end
    // 设置自定义按钮的默认值

    setDefualtButtonList() {
      !this.formOperation.buttonList && (this.formOperation.buttonList = [])
      this.buttonList = this.formOperation.buttonList
    },

    // 设置自定义按钮集的样式
    setButtonListClassName() {
      this.buttonList.forEach(btn => {
        isEmptyValue(btn.class)
          ? (btn.class = this.defaultClassName)
          : (btn.class = this.defaultClassName + ' ' + btn.class)
      })
    },

    // 按钮方法的执行
    buttonCB(methodName, el) {
      // console.log(methodName)
      this[methodName](el)
    },

    // 取消操作
    formCancel(el) {
      this.$emit('formCancel', el)
    },
    // 保存操作
    formSave(el) {
      this.$emit('formSave', el)
    },

    buttonListMethodCB(methodName, el) {
      // console.log(methodName, el)
      this.$emit('buttonListMethodCB', methodName, el)
    }
  }
}
</script>

<style></style>
